/**
 *  Created on  : 22/05/2012
 *  Author      : Ing. Javier Silva Pérez - [javier]
 *  Description :
 *  	
 */
package cinvestav.cryptography.pki.android.utils;

import java.math.BigInteger;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Date;
import java.util.HashMap;

import cinvestav.cryptography.pki.android.exception.AndroidCryptoUtilsException;
import cinvestav.cryptography.pki.android.key.RSAKeyPair;
import cinvestav.cryptography.pki.android.key.RSAPrivateKey;
import cinvestav.cryptography.pki.android.key.RSAPublicKey;

/**
 * Interface for X509 Certiticate Utils, contains common functions for x509
 * certificate
 * 
 * @author Ing. Javier Silva Pérez - [javier]
 * @since 22/05/2012
 * @version 1.0
 */
public interface IAndroidX509CertificateUtils {

	/**
	 * Create Root X509 v3 Certificate for RSA Keys
	 * 
	 * @param pubKey
	 *            Public Key to be certified
	 * @param caPrivKey
	 *            PrivateKey of the signer CA
	 * @param serial
	 *            Serial Number for the certificate
	 * @param notBefore
	 *            Not Before Validity date
	 * @param notAfter
	 *            Not After Validity date
	 * @param caCert
	 *            CA PublicKey Certificate
	 * @param certificateInformationMap
	 *            Map filled out with the certificate information using the
	 *            Field key (
	 *            {@link cinvestav.cryptography.pki.android.cert.CertificateInformationKeys}
	 *            Supported Keys) and the field value
	 * @see cinvestav.cryptography.pki.android.cert.CertificateInformationKeys
	 * @return A new signed X509 Public key certificate
	 * @throws AndroidCryptoUtilsException
	 *             If something goes wrong
	 */
	public Certificate createV3Cert(RSAPublicKey pubKey, RSAPrivateKey privKey,
			BigInteger serial, Date notBefore, Date notAfter,
			HashMap<String, String> certificateInformationMap)
			throws AndroidCryptoUtilsException;

	/**
	 * Create X509 v3 Certificate for RSA Keys
	 * 
	 * @param pubKey
	 *            Public Key to be certified
	 * @param caPrivKey
	 *            PrivateKey of the signer CA
	 * @param serial
	 *            Serial Number for the certificate
	 * @param notBefore
	 *            Not Before Validity date
	 * @param notAfter
	 *            Not After Validity date
	 * @param caCert
	 *            CA PublicKey Certificate
	 * @param certificateInformationMap
	 *            Map filled out with the certificate information using the
	 *            Field key (
	 *            {@link cinvestav.cryptography.pki.android.cert.CertificateInformationKeys}
	 *            Supported Keys) and the field value
	 * @see cinvestav.cryptography.pki.android.cert.CertificateInformationKeys
	 * @return A new signed X509 Public key certificate
	 * @throws AndroidCryptoUtilsException
	 *             If something goes wrong
	 */
	public Certificate createV3Cert(RSAPublicKey pubKey,
			RSAPrivateKey caPrivKey, BigInteger serial, Date notBefore,
			Date notAfter, X509Certificate caCert,
			HashMap<String, String> certificateInformationMap)
			throws AndroidCryptoUtilsException;

	/**
	 * Creates a new PKCS12 file, in which is stored the RSA SubjetsPrivate key
	 * protected by PBE and the certificate chain for the corresponding public
	 * key
	 * 
	 * @param fileName
	 *            File name for the pkcs12 file (commonly with extension .p12)
	 * @param subjectKeyPair
	 *            Subject RSA Key Pair
	 * @param keyStorePwd
	 *            Password for the pkcs12 file
	 * @param privKeyPwd
	 *            File for the encrypting the private key
	 * @param chain
	 *            Certificate Chain, must include at least one, containing the
	 *            subject public key
	 * @throws AndroidCryptoUtilsException
	 */
	public void savePKCS12(String fileName, RSAKeyPair subjectKeyPair,
			String keyStorePwd, String privKeyPwd, Certificate[] chain)
			throws AndroidCryptoUtilsException;

	/**
	 * Stores a certificate in disk using the specified fileName and DER as
	 * default encoding
	 * 
	 * @param fileName
	 *            File Name for the certificate, must include the full path in
	 *            which will be saved
	 * @param certificate
	 *            Certificate to be saved
	 * @throws AndroidCryptoUtilsException
	 *             If unsupported encoding is selected, or something goes wrong
	 *             while writing the certificate
	 */
	public void saveCertificate(String fileName, Certificate certificate)
			throws AndroidCryptoUtilsException;

	/**
	 * Stores a certificate in disk using the specified fileName and the
	 * selected encoding
	 * 
	 * @param fileName
	 *            File Name for the certificate, must include the full path in
	 *            which will be saved
	 * @param certificate
	 *            Certificate to be saved
	 * @param encoding
	 *            Encoding to be used for save the certificate
	 * @throws AndroidCryptoUtilsException
	 *             If unsupported encoding is selected, or something goes wrong
	 *             while writing the certificate
	 */
	public void saveCertificate(String fileName, Certificate certificate,
			String encoding) throws AndroidCryptoUtilsException;

	/**
	 * Load a X509 certificate using an specific encoding from file
	 * 
	 * @param fileName
	 *            Full path and name of the file containing the x509 certificate
	 * @param encoding
	 *            Encoding of the certificate, could be DER or PEM
	 * @return X509 certificate contained in the file
	 * @throws AndroidCryptoUtilsException
	 *             If the certificate could not be loaded, because wrong
	 *             encoding selected or the file does not contain a valid X509
	 *             certificate
	 */
	public Certificate loadCertificate(String fileName, String encoding)
			throws AndroidCryptoUtilsException;

	/**
	 * Load a X509 certificate, this function tries both supported encoding
	 * types, so it could be a bit slower than the function in which the encoded
	 * is selected
	 * 
	 * @param fileName
	 *            Full path and name of the file containing the x509 certificate
	 * @return X509 certificate contained in the file
	 * @throws AndroidCryptoUtilsException
	 *             If the certificate could not be loaded, because file does not
	 *             contain a valid X509 certificate
	 */
	public Certificate loadCertificate(String fileName)
			throws AndroidCryptoUtilsException;

	/**
	 * Loads the RSA Key Pair stored in a pkcs12
	 * 
	 * @param fileName
	 *            File in which are stored the keys
	 * @param keyStorePwd
	 *            PKCS12 File password
	 * @param privKeyPwd
	 *            PrivateKey Password
	 * @return RSAKeyPair stored in the pkcs12 file
	 * @throws AndroidCryptoUtilsException
	 */
	public RSAKeyPair loadRSAKeyPairPKCS12(String fileName, String keyStorePwd,
			String privKeyPwd) throws AndroidCryptoUtilsException;

	/**
	 * Load the certificate
	 * 
	 * @param fileName
	 * @param keyStorePwd
	 * @param privKeyPwd
	 * @return The certificate chain array stored in the pkcs12 file
	 * @throws AndroidCryptoUtilsException
	 */
	public Certificate[] loadCertificateChainPKCS12(String fileName,
			String keyStorePwd, String privKeyPwd)
			throws AndroidCryptoUtilsException;
}
